﻿using H.Daos.Attributes;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace H.Daos
{
    /// <summary>
    /// 数据访问对象接口
    /// </summary>
    public interface IDao : IDisposable
    {
        /// <summary>
        /// 为一个模型更新数据库表
        /// </summary>
        /// <typeparam name="M"></typeparam>
        void UpdateTable<M>() where M : AbstractEntity;

        /// <summary>
        /// 修改数据库密码
        /// </summary>
        /// <param name="newPassword">新的数据库密码</param>
        void ChangePassword(string newPassword);

        /// <summary>
        /// 根据主键获取模型
        /// </summary>
        /// <typeparam name="M"></typeparam>
        /// <param name="id"></param>
        /// <returns>如果找到返回实体,没有找到则返回null</returns>
        M FindOne<M>(int id) where M : AbstractEntity, new();

        /// <summary>
        /// 生成一个查询模型M对应的数据库表的实例
        /// </summary>
        /// <typeparam name="M">查询对象返回的模型类型</typeparam>
        /// <param name="tableName">数据库表的名称,为空则表示自动获取</param>
        /// <returns></returns>
        IQuery<M> Query<M>(string tableName = null) where M : AbstractEntity, new();

        /// <summary>
        /// 生成一个查询某个数据库表的实例
        /// </summary>
        /// <param name="tableName">希望进行查询的数据库表名</param>
        /// <returns>返回一个查询对象</returns>
        IQuery Query(string tableName);

        /// <summary>
        /// 以指定的模型数组接收SQL语句的执行结果
        /// </summary>
        /// <typeparam name="M">返回的模型的类型</typeparam>
        /// <param name="sql">待执行的SQL语句</param>
        /// <param name="valueBindings">与SQL语句中的占位符绑定的参数值</param>
        /// <returns>返回所有的数据,并以模型的方式展示</returns>
        M[] Select<M>(string sql, KeyValuePair<string, object>[] valueBindings = null) where M : AbstractEntity, new();

        /// <summary>
        /// 保存某个模型到数据库中
        /// </summary>
        /// <typeparam name="M"></typeparam>
        /// <param name="model">需要保存的模型</param>
        /// <param name="allowUpdate">主键冲突时是否进行更新</param>
        void Save<M>(M model, bool allowUpdate = true) where M : AbstractEntity, new();

        /// <summary>
        /// 删除一个指定的模型
        /// </summary>
        /// <typeparam name="M"></typeparam>
        /// <param name="model">需要被删除的模型</param>
        void Delete<M>(M model) where M : AbstractEntity, new();

        /// <summary>
        /// 以NameValueCollection类型数组接收SQL语句的执行结果
        /// </summary>
        /// <param name="sql">待执行的SQL语句</param>
        /// <param name="valueBindings">与SQL语句中的占位符绑定的参数值</param>
        /// <returns>返回所有的数据</returns>
        NameValueCollection[] Select(string sql, KeyValuePair<string, object>[] valueBindings = null);

        /// <summary>
        /// 以指定类型数组接收一列数据
        /// </summary>
        /// <typeparam name="T">返回的值的类型</typeparam>
        /// <param name="sql">待执行的SQL语句</param>
        /// <param name="valueBindings">与SQL语句中的占位符绑定的参数值</param>
        /// <returns>返回一个列的数据组成的数组</returns>
        T[] Column<T>(string sql, KeyValuePair<string, object>[] valueBindings = null);

        /// <summary>
        /// 以指定的类型接收一个数据
        /// </summary>
        /// <typeparam name="T">返回的值的类型</typeparam>
        /// <param name="sql">待执行的SQL语句</param>
        /// <param name="valueBindings">与SQL语句中的占位符绑定的参数值</param>
        /// <returns>返回读取到的值</returns>
        T Value<T>(string sql, KeyValuePair<string, object>[] valueBindings = null);

        /// <summary>
        /// 执行语句
        /// </summary>
        /// <param name="sql">待执行的SQL语句</param>
        /// <param name="valueBindings">与SQL语句中的占位符绑定的参数值</param>
        /// <returns>返回受影响的条数</returns>
        int Execute(string sql, KeyValuePair<string, object>[] valueBindings = null);
    }
}
